package com.cea.papyrus.core.editpart;

import java.util.Iterator;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.requests.ChangeBoundsRequest;

import com.cea.papyrus.core.commands.GraphNodeSetConstraintCommand;
import com.cea.papyrus.core.figures.IAbstractElementFigure;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;

public class ContainerDimensionAdaptationEditPolicy extends DimensionAdaptationEditPolicy {
	public ContainerDimensionAdaptationEditPolicy() {
		super();
	}

	protected Command getAdaptDimensionCommand(){
		IFigure fig = getGraphNodeEditPart().getFigure();
		Dimension minimalDimension = null;

		if (fig instanceof IAbstractElementFigure){
			minimalDimension=((IAbstractElementFigure)fig).getMinimumDimension();
		}
		if(getGraphNodeEditPart().getChildren().size()==0){
			return null;
		}
		
		Dimension positiveExtension = (minimalDimension != null)?minimalDimension.getCopy():new Dimension(0, 0);
		Dimension negativeExtension = new Dimension(0, 0);
		
		CompoundCommand cc = new CompoundCommand();
		computeResizeDimension(getGraphNodeEditPart(), positiveExtension, negativeExtension, cc);
		
		cc.add(new GraphNodeSetConstraintCommand(getGraphNode(), new ChangeBoundsRequest (RequestConstants.REQ_RESIZE), new Rectangle(getGraphNode().getPosition().getTranslated(negativeExtension), positiveExtension)));
		return cc;
	}

	protected void computeResizeDimension(GraphNodeEditPart container, Dimension positiveExtension, Dimension negativeExtension, CompoundCommand cc){
		//look for childEditpart
		Iterator itEditpart = container.getChildren().iterator();
		while(itEditpart.hasNext()){
			//look for all owned element
			GraphicalEditPart currentEditpart= (GraphicalEditPart)itEditpart.next();
			//only plain elements are to be taken into account
			if(currentEditpart instanceof GraphNodeEditPart){
				Point p = ((GraphNodeEditPart)currentEditpart).getGraphNode().getPosition();				
				Dimension dim = ((GraphNodeEditPart)currentEditpart).getGraphNode().getSize();
				
				int tempwidth, tempheight;
				
				if(p.x < 0){
					negativeExtension.width = p.x-30;
					tempwidth = dim.width+60;
				}
				else
					tempwidth = p.x-negativeExtension.width+dim.width+30;
				if(p.y < 20){
					negativeExtension.height = p.y-30;
					tempheight = dim.height+60;
				}
				else
					tempheight = p.y-negativeExtension.height+dim.height+30;

				if(positiveExtension.width < tempwidth)
					positiveExtension.width = tempwidth;
				if(positiveExtension.height < tempheight)
					positiveExtension.height = tempheight;
			}
			//recursive loop
			if(!currentEditpart.getChildren().isEmpty())
				computeResizeDimension((GraphNodeEditPart)currentEditpart, positiveExtension, negativeExtension, cc);
			else{
				GraphNode current = ((GraphNodeEditPart)currentEditpart).getGraphNode();
				Dimension currentSize = current.getSize();
				Point currentPosition = current.getPosition();
				cc.add(new GraphNodeSetConstraintCommand(current, new ChangeBoundsRequest (RequestConstants.REQ_RESIZE), new Rectangle(currentPosition.x-negativeExtension.width, currentPosition.y-negativeExtension.height, currentSize.width, currentSize.height)));

			}
		}
	}
}
